home *** CD-ROM | disk | FTP | other *** search
- /* slowdes.c --
- this file contains a C-based DES algorithm implementation; the
- version is modeled after the MBB implementation for
- instructive clarity, and is not the most efficient version
- available for the C/70. It reads its key schedule and certain
- tables from files generated by associated programs ksbuild.c
- and tblbuild.c. John Linn -- 4 March 1983 */
-
- #include <stdio.h>
-
- /* data structures to be read from files */
- static long ip [2] [256];
- static long ipi [2] [256];
- static int ipis [8];
- static long snop [8] [64];
- unsigned ks [16] [4];
-
- /* rdfiles -- reads filed info, returns 1 iff success, 0 otherwise */
- int rdfiles ()
- {
- int i, j;
- FILE *fp, *fopen ();
-
- if (NULL == (fp = fopen ("ip", "r")))
- {
- printf ("dodes -- can't read file 'ip'\n");
- return (0);
- }
- for (i = 0; i < 2; i++)
- for (j = 0; j < 256; j++)
- if (EOF == fscanf (fp, "%lx", &ip [i] [j]))
- {
- printf ("dodes -- 'ip' read failed at i=%d, j=%d\n", i, j);
- return (0);
- }
- fclose (fp);
-
- if (NULL == (fp = fopen ("ipi", "r")))
- {
- printf ("dodes -- can't read file 'ipi'\n");
- return (0);
- }
- for (i = 0; i < 2; i++)
- for (j = 0; j < 256; j++)
- if (EOF == fscanf (fp, "%lx", &ipi [i] [j]))
- {
- printf ("dodes -- 'ipi' read failed at i=%d, j=%d\n", i, j);
- return (0);
- }
- fclose (fp);
-
- if (NULL == (fp = fopen ("ipis", "r")))
- {
- printf ("dodes -- can't read file 'ipis'\n");
- return (0);
- }
- for (i = 0; i < 8; i++)
- if (EOF == fscanf (fp, "%x", &ipis [i]))
- {
- printf ("dodes -- 'ipis' read failed at i=%d\n");
- return (0);
- }
- fclose (fp);
-
- if (NULL == (fp = fopen ("snop", "r")))
- {
- printf ("dodes -- can't read file 'snop'\n");
- return (0);
- }
- for (i = 0; i < 8; i++)
- for (j = 0; j < 64; j++)
- if (EOF == fscanf (fp, "%lx", &snop [i] [j]))
- {
- printf ("dodes -- 'snop' read failed at i=%d, j=%d\n", i, j);
- return (0);
- }
- fclose (fp);
-
- if (NULL == (fp = fopen ("ks", "r")))
- {
- printf ("dodes -- can't read file 'ks'\n");
- return (0);
- }
- for (i = 0; i < 16; i++)
- for (j = 0; j < 4; j++)
- if (EOF == fscanf (fp, "%x", &ks [i] [j]))
- {
- printf ("dodes -- 'ks' read failed at i=%d, j=%d\n", i, j);
- return (0);
- }
- fclose (fp);
-
- return (1); /* success */
- }
-
- /*
-
- eexpand -- this routine performs a version of the DES E
- transform, per Kent's algorithm for the MBB. It accepts an input
- long and returns its result in 4 words of an unsigned array,
- ordered (1 3) (5 7) (2 4) (6 8). Significant bits are left
- justified in 8-bit bytes in these words: the two low order bits
- will always be zeroes. This version is coded for clarity of
- correspondence to the C/30 MBB version, not taking much advantage
- of 32-bit operations.
-
- */
-
- #define MASK 0XFCFC;
-
- eexpand (inlong, outarr)
- long inlong;
- unsigned outarr [];
- {
- unsigned rega, regb, regc, regd;
- int oddbith, oddbitl, i;
-
- rega = regc = (unsigned) (0XFFFFL & (inlong >> 16)); /* high bits */
- regb = regd = (unsigned) (0XFFFFL & inlong); /* low bits */
-
- /* rotate regc-regd pair right one */
- oddbith = !! (regc & 01);
- oddbitl = !! (regd & 01);
- regc >>= 1;
- regd >>= 1;
- if (oddbitl) regc |= 0X8000;
- if (oddbith) regd |= 0X8000;
-
- /* kill unused bits */
- regc &= MASK;
- regd &= MASK;
-
- /* rotate rega-regb pair left by three */
- for (i = 0; i < 3; i++)
- {
- oddbith = !! (rega & 0X8000);
- oddbitl = !! (regb & 0X8000);
- rega <<= 1;
- regb <<= 1;
- if (oddbitl) rega |= 01;
- if (oddbith) regb |= 01;
- }
-
- /* kill unused bits */
- rega &= MASK;
- regb &= MASK;
-
- outarr [0] = regc;
- outarr [1] = regd;
- outarr [2] = rega;
- outarr [3] = regb;
- }
-
- #define BINBLK 8 /* number of bytes in an encryption chunk */
- #define BINLNG 4 /* the number of bytes in 32 bits of a long */
-
- /* doip -- use ip table to permute 64 bits from inar to outar */
- doip (inar, outar)
- long inar [2];
- long outar [2];
- {
- extern long ip [2] [256];
-
- int i,j;
-
- outar [0] = outar [1] = 0L;
-
- for (i = 0; i < BINBLK; i++) /* input is 8 bytes */
- /* msb of inar [0] ... lsb of inar [1] */
- {
- for (j = 0; j < 2; j++) /* scan from r -> l */
- outar [j] |= ip [j] [0XFF & ((i < BINLNG) ?
- ((int) ((inar [1] >> (i * 8)))) :
- ((int) ((inar [0] >> ((i - BINLNG) * 8)))) )];
-
- if (i == (BINBLK - 1)) break; /* don't shift an extra time */
-
- for (j = 0; j < 2; j++) outar [j] <<= 1;
- }
- }
-
- /* doipi -- use ipi, ipis to perform ip-inverse */
- doipi (inar, outar)
- long inar [2];
- long outar [2];
- {
- extern int ipis [8];
- extern long ipi [2] [256];
-
- int i, j, bp;
-
- outar [0] = outar [1] = 0L;
-
- for (i = 0; i < BINBLK; i++) /* input is 8 bytes */
- {
- bp = ipis [i] - 1; /* translate byte indexes to zero origin */
-
- for (j = 0; j < 2; j++)
- outar [j] |= ipi [j] [0XFF & ((bp < BINLNG) ?
- ((int) (inar [0] >> (((BINLNG - bp) - 1) * 8))) :
- ((int) (inar [1] >> (((BINLNG - (bp-4)) - 1) * 8))) )];
-
- if (i == (BINBLK - 1)) break;
-
- for (j = 0; j < 2; j++) outar [j] <<= 1;
- }
- }
-
- /* des_encrypt -- encrypt a block under key sched in ks */
- des_encrypt (inar, outar)
- long inar [2];
- long outar [2];
- {
- extern unsigned ks [16] [4];
- extern long snop [8] [64];
-
- int round, i, j;
- unsigned expan [4]; /* receives output of E transform */
- long sbout, scopy;
- long oarr [2];
-
- doip (inar, outar);
-
- for (round = 0; round < 16; round++)
- {
- sbout = 0L;
-
- eexpand (outar [1], expan);
-
- for (i = 0; i < 4; i++)
- {
- expan [i] ^= ks [round] [i];
-
- for (j = 0; j < 2; j++)
- {
- sbout |= snop [(i*2)+j]
- [0X3F & (j ? (expan [i] >> 2) : (expan [i] >> 10))];
- }
- }
-
- scopy = outar [0];
- outar [0] = outar [1];
- outar [1] = scopy ^ sbout;
- }
-
- /* a final swap */
- scopy = outar [0];
- outar [0] = outar [1];
- outar [1] = scopy;
-
- doipi (outar, oarr); /* perform ip-inverse into temp copy */
- outar [0] = oarr [0];
- outar [1] = oarr [1];
- }
-
- /* des_decrypt -- decrypt a block under key sched in ks */
- des_decrypt (inar, outar)
- long inar [2];
- long outar [2];
- {
- extern unsigned ks [16] [4];
- extern long snop [8] [64];
-
- int round, i, j;
- unsigned expan [4]; /* receives output of E transform */
- long sbout, scopy;
- long oarr [2];
-
- doip (inar, outar);
-
- for (round = 15; round >= 0; round--)
- /* to do a DES decrypt, use key schedule in reverse order */
- {
- sbout = 0L;
-
- eexpand (outar [1], expan);
-
- for (i = 0; i < 4; i++)
- {
- expan [i] ^= ks [round] [i];
-
- for (j = 0; j < 2; j++)
- {
- sbout |= snop [(i*2)+j]
- [0X3F & (j ? (expan [i] >> 2) : (expan [i] >> 10))];
- }
- }
-
- scopy = outar [0];
- outar [0] = outar [1];
- outar [1] = scopy ^ sbout;
- }
-
- /* a final swap */
- scopy = outar [0];
- outar [0] = outar [1];
- outar [1] = scopy;
-
- doipi (outar, oarr); /* perform ip-inverse into temp copy */
- outar [0] = oarr [0];
- outar [1] = oarr [1];
- }
-
-
-